package com.zengdada.authority.config;

import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;

import java.util.Collections;
import java.util.HashMap;

/**
 * Created by guozp on 2017/8/29.
 */
//@Component 事务依然生效
@Configuration
public class TxConfigBeanName {
    @Value("${database.transaction.required.timeout:5}")
    Integer timeout;

    /*事务拦截类型*/
    @Bean("txSource")
    public TransactionAttributeSource transactionAttributeSource() {
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        /*只读事务，不做更新操作*/
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setReadOnly(true);
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
        /*当前存在事务就使用当前事务，当前不存在事务就创建一个新的事务*/
        //RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        //requiredTx.setRollbackRules(
        //  Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        //requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,
                Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        requiredTx.setTimeout(timeout);
        source.setNameMap(new HashMap<String, TransactionAttribute>() {{
            put("add*", requiredTx);
            put("save*", requiredTx);
            put("insert*", requiredTx);
            put("update*", requiredTx);
            put("delete*", requiredTx);
            put("create*", requiredTx);
            put("get*", readOnlyTx);
            put("query*", readOnlyTx);
            put("find*", readOnlyTx);
        }});
        return source;
    }

    /**
     * 切面拦截规则 参数会自动从容器中注入
     */
    @Bean
    public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor) {
        AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        pointcutAdvisor.setAdvice(txInterceptor);
        pointcutAdvisor.setExpression("execution (* com.sybenya.*.service.impl.*.*(..))");
        return pointcutAdvisor;
    }

    /*事务拦截器*/
    @Bean("txInterceptor")
    TransactionInterceptor getTransactionInterceptor(PlatformTransactionManager tx) {
        return new TransactionInterceptor(tx, transactionAttributeSource());
    }
}

//import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//import org.springframework.transaction.interceptor.TransactionInterceptor;
//
//import java.util.Properties;
//
////@Component
//@Configuration
//public class TxConfigBeanName {
//
//    @Autowired
//    private DataSourceTransactionManager transactionManager;
//
//    // 创建事务通知
//
//    @Bean(name = "txAdvice")
//    public TransactionInterceptor getAdvisor() throws Exception {
//
//        Properties properties = new Properties();
//        properties.setProperty("insert*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("create*", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        properties.setProperty("get*", "PROPAGATION_SUPPORTS,-Exception,readOnly");
//        properties.setProperty("select*", "PROPAGATION_SUPPORTS,-Exception,readOnly");
//        properties.setProperty("find*", "PROPAGATION_SUPPORTS,-Exception,readOnly");
//
//        TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, properties);
//        return tsi;
//
//    }
//
//    @Bean
//    public BeanNameAutoProxyCreator txProxy() {
//        BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
//        creator.setInterceptorNames("txAdvice");
//        creator.setBeanNames("*Service", "*ServiceImpl");
//        creator.setProxyTargetClass(true);
//        return creator;
//    }
//}

